/*******************************************************************************************
*文件:    s7comm.h
*描述:    S7协议分析
*
*作者:    刘涛
*日期:    2017-03-28
*修改:    创建文件                            ------>     2017-03-28
*         修改接口定义                        ------>     2017-03-30
*         修改程序结构，进行代码分层处理      ------>     2017-05-05
*         增加TPKT和COTP检查                  ------>     2017-05-11
*
*******************************************************************************************/
#include "datatype.h"

class CS7COMM: public PROTOCOLS
{
public:
    CS7COMM();
    virtual ~CS7COMM() {};

    int32 initialize(const pchar verdict);
    int32 version(pchar version);
    int32 dofilter_src(const pchar data, int32 size, const pchar rule, int32 filter, pchar msgout);
    int32 dofilter_dst(const pchar data, int32 size, const pchar rule, int32 filter, pchar msgout);

private:
    static const pchar VERSION;
    static const pchar MODULE;
    static const pchar REGKEY;

    //s7comm rule
    typedef struct _s7commrule {
        uint8 rosctr;  //rosctr
        uint8 func;   //job+ack,function
        uint8 type;    //user_data:type
        uint8 func_grp; //user_data:function group
        uint8 sub_func; //user_data:sub function
        int32 index;    //索引
        int32 sub_index;//子索引值
    } S7COMMRULE, *PS7COMMRULE;

    //记录当前规则
    struct {
        char rule[1000];
        int32 filter;
    } rulebak;

    //规则解析记录
    std::vector<std::string> cmdlist;        //3个一组，表示匹配规则
    std::vector<std::string> funcgrplist;
    std::vector<std::string> subfunclist;

    int32   GetCmd( PS7COMMSTATE s7comm_state, PS7COMMRULE s7comm_rule);
    int32   GetRule( const pchar rule, int32 filter );

    int32   FilterUserData( PS7COMMRULE s7comm_rule, pchar msgout ); //filter user_data
    int32   FilterData( PS7COMMRULE s7comm_rule, int32 size, pchar msgout ); //filter s7 data

    int32   S7UDPduMap( PS7COMMSTATE src_data, uint8 map_type ); //map user_data pdu
    int32   S7FuncNameMap( uint8 value, uint8 sub_value, uint8 map_type ); //map job,ack和ack_data

    int32   CheckS7Header( const pchar data, int32 size, uint32 offset, PS7COMMSTATE s7comm_state);
    int32   S7HeaderCheck( PS7COMMSTATE s7comm_state );  //s7 header check
    int32   CheckS7JobPdu( PS7COMMSTATE job_data, pint32 index );  //check job
    int32   CheckS7AckPdu( PS7COMMSTATE ack_data, pint32 index );  //check ack和ack_data
    int32   CheckS7UserDataPdu( PS7COMMSTATE user_data, pint32 index, pint32 sub_index );    //check user_data

    void    CopyPduToRule(PS7COMMSTATE s7comm_state, PS7COMMRULE s7comm_rule, \
                          int32 index, int32 sub_index);//将s7comm_state里面的数值拷贝到s7comm_rule中
    int32   CheckS7DataEmpty( PS7COMMSTATE s7comm_state, PS7COMMRULE s7comm_rule );   //dta_len=0
    int32   CheckS7DataExist( PS7COMMSTATE s7comm_state, PS7COMMRULE s7comm_rule );   //data_len>0

    int32   S7RuleParamCheck( std::vector<std::string> &list,  uint8 map_type, PS7COMMRULE s7comm_rule );
    int32   CheckFunctype(uint8 functype);//检查functype

    uint8   CheckTpkt(const uint8 *pkt, uint32 len);//传输层TPKT协议处理：判断数据是否收完
    uint32  GetCotpOffset(const uint8 *buffer);//传输层COTP协议处理
	uint8   GetCotpType(const uint8 *buffer);

    uint32  CheckTpktCotp(const uint8 *data, uint32 size); //检查TPKT+COTP
};
